home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange '98 presents:
-
- Need For Speed 3: Hot Pursuit - CD crack by Static Vengeance - Oct 7th, 1998
-
- Need for Speed 3: Hot Pursuit (NFS3) is an awesome new racing game. The graphics on a 3Dfx based
- card are fantasic and game speed is great. You can play a multi player game on-line or in split screen
- mode. You have the option of racing alone or in the "Hot Pursuit" mode in which you're chased by cops.
- You can choose which type of car you want to drive. Then you also have the option of downloading new cars
- off the web and eventually new tracks. Electronic Arts has put out a patch that will automaticly check
- EA's ftp site and check if there is newer version of NFS3. If there is, the "Network Play System" will
- download and install the latest patch/update for you.
- With such a great game there is little wonder that there is some type of copy protection included.
- The first thing that needs to be done is to install the game. Check out what has been installed versus what
- files are still on the CD. You will see that not all the files used are copied from NFS3 CD. In fact there
- are a lot of audio files and the movies files that are not copied. Load up the file install.win with note
- pad and you'll see path directories used by the game. Any path that has your CD rom drive letter in it means
- those files are stored on the CD.
- One option is to copy the directories (with all thier files) to your hard drive, then edit install.win
- to point to the new locations. This will work except it takes over 500 megs of hard drive space to do. Then
- there is still the CD check. This will be our first objective, remove the CD check.
- Using W32Dasm, disassemble nfs3.exe and look for useful data string references. Eventually you come
- acrros "C:NFS3.EXE" and "A:\" Double click on the "A:\" and you'll be in the middle of this routine:
-
- * Referenced by a CALL at Addresses:
- |:004B657B , :004B65DC <-- Called twice
- |
- :004F9820 51 push ecx
- :004F9821 52 push edx
- :004F9822 56 push esi
- :004F9823 57 push edi
- :004F9824 83EC04 sub esp, 00000004
- :004F9827 89C2 mov edx, eax
-
- * Possible StringData Ref from Data Obj ->"A:\" <-- Commonly used in CD checks
- |
- :004F9829 BE24E95400 mov esi, 0054E924
- :004F982E 89E7 mov edi, esp
- :004F9830 57 push edi
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F9847(C)
- |
- :004F9831 8A06 mov al, byte ptr [esi]
- :004F9833 8807 mov byte ptr [edi], al
- :004F9835 3C00 cmp al, 00
- :004F9837 7410 je 004F9849
- :004F9839 8A4601 mov al, byte ptr [esi+01]
- :004F983C 83C602 add esi, 00000002
- :004F983F 884701 mov byte ptr [edi+01], al
- :004F9842 83C702 add edi, 00000002
- :004F9845 3C00 cmp al, 00
- :004F9847 75E8 jne 004F9831
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F9837(C)
- |
- :004F9849 5F pop edi
- :004F984A 001424 add byte ptr [esp], dl
- :004F984D 89E0 mov eax, esp
- :004F984F 50 push eax
-
- * Reference To: KERNEL32.GetDriveTypeA, Ord:0025h <-- Commonly used in CD check routines
- |
- :004F9850 2EFF1518555300 Call dword ptr cs:[00535518]
- :004F9857 83F805 cmp eax, 00000005 <-- 05 is the value of a CD rom drive
- :004F985A 7515 jne 004F9871
- :004F985C B801000000 mov eax, 00000001 <-- Load eax with 01 for finding CD drive
- :004F9861 83C404 add esp, 00000004
- :004F9864 5F pop edi
- :004F9865 5E pop esi
- :004F9866 5A pop edx
- :004F9867 59 pop ecx
- :004F9868 8D8000000000 lea eax, dword ptr [eax+00000000]
- :004F986E 8BD2 mov edx, edx
- :004F9870 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F985A(C)
- |
- :004F9871 31C0 xor eax, eax <-- Eax = zero for no CD rom drive in system
- :004F9873 83C404 add esp, 00000004
- :004F9876 5F pop edi
- :004F9877 5E pop esi
- :004F9878 5A pop edx
- :004F9879 59 pop ecx
- :004F987A C3 ret
-
- That routine was somewhat short, so now we'll look at the calling routine:
-
- * Referenced by a CALL at Address:
- |:004A4227 <-- Called once
- |
- :004B6540 53 push ebx
- :004B6541 51 push ecx
- :004B6542 52 push edx
- :004B6543 56 push esi
- :004B6544 57 push edi
- :004B6545 55 push ebp
- :004B6546 89E5 mov ebp, esp
- :004B6548 81EC3C010000 sub esp, 0000013C
- :004B654E 8D7DF4 lea edi, dword ptr [ebp-0C]
- :004B6551 BB00010000 mov ebx, 00000100
-
- * Possible StringData Ref from Code Obj ->"C:NFS3.EXE" <-- File to search for
- |
- :004B6556 BEA8584B00 mov esi, 004B58A8
-
- * Possible StringData Ref from Data Obj ->"install.win"
- |
- :004B655B BA340E5400 mov edx, 00540E34
- :004B6560 8D85C4FEFFFF lea eax, dword ptr [ebp+FFFFFEC4]
- :004B6566 A5 movsd
- :004B6567 A5 movsd
- :004B6568 66A5 movsw
- :004B656A A4 movsb
- :004B656B E830320400 call 004F97A0
- :004B6570 8D85C4FEFFFF lea eax, dword ptr [ebp+FFFFFEC4]
- :004B6576 E885320400 call 004F9800
- :004B657B E8A0320400 call 004F9820 <-- Check for a CD rom drive on system
- :004B6580 85C0 test eax, eax
- :004B6582 7430 je 004B65B4
- :004B6584 B906000000 mov ecx, 00000006
- :004B6589 8D7DDC lea edi, dword ptr [ebp-24]
- :004B658C BEB4584B00 mov esi, 004B58B4
- :004B6591 6A30 push 00000030
- :004B6593 A150AA7A00 mov eax, dword ptr [007AAA50]
- :004B6598 F3 repz
- :004B6599 A5 movsd
-
- * Possible StringData Ref from Data Obj ->"Need For Speed 3"
- |
- :004B659A 68400E5400 push 00540E40
- :004B659F 8B5485DC mov edx, dword ptr [ebp+4*eax-24]
- :004B65A3 52 push edx
- :004B65A4 6A00 push 00000000
-
- * Reference To: USER32.MessageBoxA, Ord:001Fh
- |
- :004B65A6 2EFF1564575300 Call dword ptr cs:[00535764]
- :004B65AD 31C0 xor eax, eax
- :004B65AF E890990200 call 004DFF44
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B6582(C)
- |
- :004B65B4 E807FFFFFF call 004B64C0
- :004B65B9 85C0 test eax, eax
- :004B65BB 755A jne 004B6617
- :004B65BD 31D2 xor edx, edx
- :004B65BF EB19 jmp 004B65DA
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B65E3(C)
- |
- :004B65C1 88D0 mov al, dl
- :004B65C3 0441 add al, 41
- :004B65C5 8845F4 mov byte ptr [ebp-0C], al
- :004B65C8 8D45F4 lea eax, dword ptr [ebp-0C]
- :004B65CB E8C0A70300 call 004F0D90
- :004B65D0 85C0 test eax, eax
- :004B65D2 7543 jne 004B6617
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B65E5(U)
- |
- :004B65D4 42 inc edx
- :004B65D5 83FA1A cmp edx, 0000001A
- :004B65D8 7D0D jge 004B65E7
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B65BF(U)
- |
- :004B65DA 89D0 mov eax, edx
- :004B65DC E83F320400 call 004F9820 <-- Check again for a CD rom drive
- :004B65E1 85C0 test eax, eax
- :004B65E3 75DC jne 004B65C1
- :004B65E5 EBED jmp 004B65D4
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B65D8(C)
- |
- :004B65E7 B906000000 mov ecx, 00000006
- :004B65EC 8D7DC4 lea edi, dword ptr [ebp-3C]
- :004B65EF BECC584B00 mov esi, 004B58CC
- :004B65F4 6A30 push 00000030
- :004B65F6 A150AA7A00 mov eax, dword ptr [007AAA50]
- :004B65FB F3 repz
- :004B65FC A5 movsd
-
- * Possible StringData Ref from Data Obj ->"Need For Speed 3"
- |
- :004B65FD 68400E5400 push 00540E40
- :004B6602 8B4C85C4 mov ecx, dword ptr [ebp+4*eax-3C]
- :004B6606 51 push ecx
- :004B6607 6A00 push 00000000
-
- * Reference To: USER32.MessageBoxA, Ord:001Fh
- |
- :004B6609 2EFF1564575300 Call dword ptr cs:[00535764]
- :004B6610 31C0 xor eax, eax
- :004B6612 E82D990200 call 004DFF44
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004B65BB(C), :004B65D2(C)
- |
- :004B6617 89EC mov esp, ebp
- :004B6619 5D pop ebp
- :004B661A 5F pop edi
- :004B661B 5E pop esi
- :004B661C 5A pop edx
- :004B661D 59 pop ecx
- :004B661E 5B pop ebx
- :004B661F C3 ret
-
- That was the heart of the CD check. It was only called once so let's check out the code
- that surounds the call to the CD check:
-
- -- Program code --
- :004A421E 7507 jne 004A4227
- :004A4220 31C0 xor eax, eax
- :004A4222 E8491E0100 call 004B6070
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004A421E(C)
- |
- :004A4227 E814230100 call 004B6540 <-- Check for the CD
- :004A422C E81FF6FFFF call 004A3850
- :004A4231 F6059A5E560020 test byte ptr [00565E9A], 20
- :004A4238 7465 je 004A429F
- :004A423A B801000000 mov eax, 00000001
- -- Continuing program code --
-
- Well, there is no type of check for any returned result so overwriting this call will kill the
- CD check. That was simple enough, now on to the harder stuff.
- Filling up 500+ megs of hard drive space just isn't reasonable. Time to start freeing up space.
- First thing we don't need is to see the movies time and time again. Killing the intro movies is easy by
- searching for titleav.mad you'll find this routine:
-
-
- :00496733 A1A4317A00 mov eax, dword ptr [007A31A4]
- :00496738 2B05B4585600 sub eax, dword ptr [005658B4]
- :0049673E 3D00140000 cmp eax, 00001400 <-- Time for the "atract" mode
- :00496743 7D08 jge 0049674D <-- Do intro / demo movies
- :00496745 31C0 xor eax, eax
- :00496747 5D pop ebp
- :00496748 5E pop esi
- :00496749 5A pop edx
- :0049674A 59 pop ecx
- :0049674B 5B pop ebx
- :0049674C C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00496743(C)
- | <-- Get's here by conditional jump
- :0049674D E87EA3F7FF call 00410AD0
- :00496752 A1B8585600 mov eax, dword ptr [005658B8]
- :00496757 83F803 cmp eax, 00000003
- :0049675A 7726 ja 00496782
- :0049675C FF2485B0664900 jmp dword ptr [4*eax+004966B0]
-
- * Possible StringData Ref from Data Obj ->"titleav.mad" <-- The title movie
- |
- :00496763 B878CF5300 mov eax, 0053CF78
- :00496768 EB13 jmp 0049677D
-
- * Possible StringData Ref from Data Obj ->"demoav1.mad"
- |
- :0049676A B884CF5300 mov eax, 0053CF84
- :0049676F EB0C jmp 0049677D
-
- * Possible StringData Ref from Data Obj ->"demoav2.mad"
- |
- :00496771 B890CF5300 mov eax, 0053CF90
- :00496776 EB05 jmp 0049677D
-
- * Possible StringData Ref from Data Obj ->"demoav3.mad"
- |
- :00496778 B89CCF5300 mov eax, 0053CF9C
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:00496768(U), :0049676F(U), :00496776(U)
- |
- :0049677D E81EFEFFFF call 004965A0
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0049675A(C)
- |
- :00496782 B816000000 mov eax, 00000016
- :00496787 8B15E82B7000 mov edx, dword ptr [00702BE8]
- :0049678D 31DB xor ebx, ebx
- -- Continuing program code --
-
- No problem here, this one is actually kind of easy! Just kill the conditional jump and no more
- title movies or demo movies. Alright, one down lot's more to go:
- Time to get rid of some of the audio. The audio that'll have to go is the music at the main menu
- and the music that gets played during the actual racing of tracks. Music files are in ".mus" format and
- there just happens to be a data string ref of the same name. Double click on it and you're here:
-
- * Referenced by a CALL at Addresses:
- |:004104BE , :004104FA , :0041054B , :00410597 , :004105E4
- |:0044B5DB , :0049678F , :004C42B7 <-- Called 8 times
- |
- :004105F0 51 push ecx
- :004105F1 56 push esi
- :004105F2 57 push edi
- :004105F3 55 push ebp
- :004105F4 89E5 mov ebp, esp
- :004105F6 81EC0C020000 sub esp, 0000020C
- :004105FC 81ED8A020000 sub ebp, 0000028A
- :00410602 898586020000 mov dword ptr [ebp+00000286], eax
- :00410608 89957E020000 mov dword ptr [ebp+0000027E], edx
- :0041060E C78582020000DC050000 mov dword ptr [ebp+00000282], 000005DC
- :00410618 83F863 cmp eax, 00000063 <-- My original patch went here
- :0041061B 7508 jne 00410625
- :0041061D 31F6 xor esi, esi
- :0041061F 89B586020000 mov dword ptr [ebp+00000286], esi
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0041061B(C)
- |
- :00410625 30E4 xor ah, ah
- :00410627 BF63000000 mov edi, 00000063
-
-
- -- Snip large chunk of code --
-
- :00410823 BA10000000 mov edx, 00000010
- :00410828 8D857E010000 lea eax, dword ptr [ebp+0000017E]
- :0041082E E8CD080D00 call 004E1100
- :00410833 A3507A5700 mov dword ptr [00577A50], eax
- :00410838 E80B6E0D00 call 004E7648
-
- * Possible StringData Ref from Data Obj ->".mus" <-- Data ref that got us here
- |
- :0041083D 68A0795300 push 005379A0
- :00410842 8D457E lea eax, dword ptr [ebp+7E]
- :00410845 50 push eax
-
- * Possible StringData Ref from Data Obj ->"%s%s"
- |
- :00410846 683C795300 push 0053793C
- :0041084B 8D857E010000 lea eax, dword ptr [ebp+0000017E]
- -- More code --
-
- Once I found the ref in the code I just backed up until I found the beginning of the routine.
- Then I needed a way to get to the end doing as little as possible. So I put a jump in the code at
- 410618 that jumps down the end of this routine. Then after talking with shadowRUNNER (of Crackstore,
- the best site on the web for game cracks and also the home of all my tutorials. www.crackstore.com)
- I found putting a ret (hex code C3) as the first instruction of this routine is an easy way to kill
- all calls to it. Thanks shadowRUNNER for that tip.
- That's only part of the music routines. Well also need to search for "tech" that'll lead us
- to another routine that either plays techno or rock music. That routine is coded like this:
-
- * Referenced by a CALL at Addresses:
- |:0043842A , :004A3C81 <-- Called twice
- |
- :004108C0 51 push ecx
- :004108C1 56 push esi
- :004108C2 57 push edi
- :004108C3 55 push ebp
- :004108C4 89E5 mov ebp, esp
- :004108C6 81EC08010000 sub esp, 00000108
- :004108CC 81ED86010000 sub ebp, 00000186
- :004108D2 899582010000 mov dword ptr [ebp+00000182], edx
- :004108D8 C7857E010000DC050000 mov dword ptr [ebp+0000017E], 000005DC
- :004108E2 83F863 cmp eax, 00000063
- :004108E5 7502 jne 004108E9
- :004108E7 31C0 xor eax, eax
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004108E5(C)
- |
- :004108E9 30D2 xor dl, dl
- :004108EB 8B0D542B7000 mov ecx, dword ptr [00702B54]
- :004108F1 881550355500 mov byte ptr [00553550], dl
- :004108F7 85C9 test ecx, ecx
- :004108F9 0F85C2010000 jne 00410AC1
- :004108FF 833D149C550000 cmp dword ptr [00559C14], 00000000
- :00410906 0F84B5010000 je 00410AC1
- :0041090C 83F80A cmp eax, 0000000A
- :0041090F 0F8DAC010000 jnl 00410AC1
- :00410915 85DB test ebx, ebx
- :00410917 7410 je 00410929
- :00410919 B601 mov dh, 01
- :0041091B 890D189C5500 mov dword ptr [00559C18], ecx
- :00410921 883550355500 mov byte ptr [00553550], dh
- :00410927 EB0A jmp 00410933
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410917(C)
- |
- :00410929 C705189C550001000000 mov dword ptr [00559C18], 00000001
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410927(U)
- |
- :00410933 740F je 00410944
- :00410935 A1B8355500 mov eax, dword ptr [005535B8]
- :0041093A 8B0C8568355500 mov ecx, dword ptr [4*eax+00553568]
- :00410941 51 push ecx
- :00410942 EB08 jmp 0041094C
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410933(C)
- |
- :00410944 8B348568355500 mov esi, dword ptr [4*eax+00553568]
- :0041094B 56 push esi
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410942(U)
- |
- :0041094C 68349A7A00 push 007A9A34
-
- * Possible StringData Ref from Data Obj ->"%s%s"
- |
- :00410951 683C795300 push 0053793C
- :00410956 8D457E lea eax, dword ptr [ebp+7E]
- :00410959 50 push eax
- :0041095A E871EF0C00 call 004DF8D0
- :0041095F 83C410 add esp, 00000010
- :00410962 8A0D9A5E5600 mov cl, byte ptr [00565E9A]
- :00410968 F6C110 test cl, 10
- :0041096B 7534 jne 004109A1
- :0041096D F6C120 test cl, 20
- :00410970 752F jne 004109A1
- :00410972 F6059B5E560001 test byte ptr [00565E9B], 01
- :00410979 7526 jne 004109A1
- :0041097B 8B3DE42B7000 mov edi, dword ptr [00702BE4]
- :00410981 83FF01 cmp edi, 00000001
- :00410984 7507 jne 0041098D
-
- * Possible StringData Ref from Data Obj ->"tech" <-- Ref that got us here
- |
- :00410986 BE88795300 mov esi, 00537988
- :0041098B EB19 jmp 004109A6
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410984(C)
- |
- :0041098D 85FF test edi, edi
-
- Okay, we'll need to take a look at the two callers to the above code and see what they do.
- The first routine:
-
- -- Program code --
- :00438426 89F2 mov edx, esi
- :00438428 31DB xor ebx, ebx
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0043841F(U)
- |
- :0043842A E89184FDFF call 004108C0 <-- Play the music
- :0043842F C605FC5B560001 mov byte ptr [00565BFC], 01
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004383D8(C), :004383FE(C), :00438408(C)
- |
- :00438436 8B5118 mov edx, dword ptr [ecx+18]
- :00438439 8B4916 mov ecx, dword ptr [ecx+16]
- -- Continuing program code --
-
- That's a short little snippet of code. The call doesn't return any special value so we'll just
- kill the call. Overwrite that call with mov eax, 00000000. Now let's check out the second caller:
-
- -- Program code --
- :004A3C7A 31DB xor ebx, ebx
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004A3C76(U)
- |
- :004A3C7C A1AC447000 mov eax, dword ptr [007044AC]
- :004A3C81 E83ACCF6FF call 004108C0 <-- Call the music routine
- :004A3C86 C605FC5B560001 mov byte ptr [00565BFC], 01
- :004A3C8D EB08 jmp 004A3C97
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004A3C64(C)
- |
- :004A3C8F 30D2 xor dl, dl
- :004A3C91 8815FC5B5600 mov byte ptr [00565BFC], dl
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004A3C8D(U)
- |
- :004A3C97 31C0 xor eax, eax
- :004A3C99 E812420400 call 004E7EB0
- -- Continuing program code --
-
- Again short so the same type of edit will work for this call as well. Alright, we have gone
- through most of the music code but there is one last one to check out. This time it was found by
- click on the "tech.mus" That'll put you in the middle of this routine:
-
- * Referenced by a CALL at Address:
- |:00478371 <-- Called once :-)
- |
- :00410130 53 push ebx
- :00410131 51 push ecx
- :00410132 52 push edx
- :00410133 56 push esi
- :00410134 57 push edi
- :00410135 55 push ebp
- :00410136 89E5 mov ebp, esp
- :00410138 81EC2C010000 sub esp, 0000012C
- :0041013E 81ED82000000 sub ebp, 00000082
- :00410144 89C1 mov ecx, eax
- :00410146 BA00000800 mov edx, 00080000
- :0041014B 31DB xor ebx, ebx
- :0041014D 8B3D542B7000 mov edi, dword ptr [00702B54]
- :00410153 895D72 mov dword ptr [ebp+72], ebx
- :00410156 895D6E mov dword ptr [ebp+6E], ebx
- :00410159 895576 mov dword ptr [ebp+76], edx
- :0041015C 85FF test edi, edi
- :0041015E 0F85B8020000 jne 0041041C
- :00410164 83F80A cmp eax, 0000000A
- :00410167 0F8DAF020000 jnl 0041041C
- :0041016D E81E370900 call 004A3890
- :00410172 833DF85B560000 cmp dword ptr [00565BF8], 00000000
- :00410179 0F859D020000 jne 0041041C
- :0041017F BB10000000 mov ebx, 00000010
- :00410184 B838795300 mov eax, 00537938
- :00410189 E8D2160D00 call 004E1860
- :0041018E 8B15E42B7000 mov edx, dword ptr [00702BE4]
- :00410194 89457A mov dword ptr [ebp+7A], eax
- :00410197 83FA03 cmp edx, 00000003
- :0041019A 0F8D92000000 jnl 00410232
- :004101A0 8B1C8D68355500 mov ebx, dword ptr [4*ecx+00553568]
- :004101A7 53 push ebx
- :004101A8 68349A7A00 push 007A9A34
-
- * Possible StringData Ref from Data Obj ->"%s%s"
- |
- :004101AD 683C795300 push 0053793C
- :004101B2 8D8556FFFFFF lea eax, dword ptr [ebp+FFFFFF56]
- :004101B8 50 push eax
- :004101B9 E812F70C00 call 004DF8D0
- :004101BE 8A259A5E5600 mov ah, byte ptr [00565E9A]
- :004101C4 83C410 add esp, 00000010
- :004101C7 F6C410 test ah, 10
- :004101CA 7534 jne 00410200
- :004101CC F6C420 test ah, 20
- :004101CF 752F jne 00410200
- :004101D1 F6059B5E560001 test byte ptr [00565E9B], 01
- :004101D8 7526 jne 00410200
- :004101DA 8B35E42B7000 mov esi, dword ptr [00702BE4]
- :004101E0 83FE01 cmp esi, 00000001
- :004101E3 7507 jne 004101EC
-
- * Possible StringData Ref from Data Obj ->"tech.mus" <-- What got us here
- |
- :004101E5 BE50795300 mov esi, 00537950
- :004101EA EB19 jmp 00410205
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004101E3(C)
- |
- :004101EC 85F6 test esi, esi
- :004101EE 7410 je 00410200
-
- Again, once I found the ref I just backed up to the start of the routine. Now we have to
- look at who called this routine and what that section of code does:
-
- * Referenced by a CALL at Address:
- |:004A396D
- |
- :00478360 55 push ebp
- :00478361 89E5 mov ebp, esp
- :00478363 833D542B700000 cmp dword ptr [00702B54], 00000000
- :0047836A 7516 jne 00478382 <-- Jump for user choosing no music?
- :0047836C A1AC447000 mov eax, dword ptr [007044AC]
- :00478371 E8BA7DF9FF call 00410130 <-- Call the music routine
- :00478376 E815B50200 call 004A3890
- :0047837B 833DF85B560000 cmp dword ptr [00565BF8], 00000000
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0047836A(C)
- |
- :00478382 5D pop ebp
- :00478383 C3 ret
-
- Very short routine here as well. There is the conditional jump at 47836A that I would say is
- used when the user selects no music during the races. But just to make sure we'll kill the call by
- overwriting it. Finally it's time to test the game after you have made these patches:
-
- CD check:
- E8 14 23 01 00 to B8 00 00 00 00 at offset 669,223
-
- Kill intro video and demo videos
- Search for: 7D 08 to 90 90 at offset 613,187
-
- Kill music at main menu and during races:
- 51 to C3 at offset 63,984
- E8 91 84 FD FF to B8 00 00 00 00 at offset 227,370
- E8 BA 7D F9 FF to B8 00 00 00 00 at offset 489,329
- E8 3A CC F6 FF to B8 00 00 00 00 at offset 667,777
-
- The game loads in and you can select the race and the car you want. Then you start the race
- and WHAM!!! NFS3 pops up with a pop-up dialog box and tells you that the "SNDpathcontrol - PATHFINDER NOT
- INITIALIZED." Well, that must come from not loading and playing the music files. So you'll need to find
- the routine that prints that message. Find the string ref and double click on it to put you here:
-
- * Referenced by a CALL at Addresses:
- |:0041363A , :00418DB6 , :00418E35 , :00418E71 , :00418EB5 <-- Called five times
- |
- :004E78DC 57 push edi
- :004E78DD 55 push ebp
- :004E78DE 803D94F6A10000 cmp byte ptr [00A1F694], 00
- :004E78E5 741C je 004E7903 <-- We want to take this jump
- :004E78E7 833DCCF6A10000 cmp dword ptr [00A1F6CC], 00000000
- :004E78EE 741B je 004E790B
- :004E78F0 85C0 test eax, eax
- :004E78F2 7C4C jl 004E7940
- :004E78F4 83F87F cmp eax, 0000007F
- :004E78F7 7F47 jg 004E7940
- :004E78F9 A256B95600 mov byte ptr [0056B956], al
- :004E78FE 31C0 xor eax, eax
- :004E7900 5D pop ebp
- :004E7901 5F pop edi
- :004E7902 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004E78E5(C)
- |
- :004E7903 B8F2FFFFFF mov eax, FFFFFFF2 <-- Get here to continue
- :004E7908 5D pop ebp
- :004E7909 5F pop edi
- :004E790A C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004E78EE(C) <-- Getting here means NFS3 had an error
- |
- * Possible StringData Ref from Data Obj ->"cmn\spathold.c"
- |
- :004E790B BF88BA5400 mov edi, 0054BA88
-
- * Possible StringData Ref from Data Obj ->"SNDpathcontrol"
- |
- :004E7910 BDA4BB5400 mov ebp, 0054BBA4
- :004E7915 B83A020000 mov eax, 0000023A
-
- * Possible StringData Ref from Data Obj ->"SNDpathcontrol - PATHFINDER NOT " <-- Print it
- ->"INITIALIZED."
- |
- :004E791A 68B4BB5400 push 0054BBB4
- :004E791F 893D50315500 mov dword ptr [00553150], edi
- :004E7925 892D54315500 mov dword ptr [00553154], ebp
- :004E792B A358315500 mov dword ptr [00553158], eax
- :004E7930 E8DB96F1FF call 00401010
- :004E7935 B8F2FFFFFF mov eax, FFFFFFF2
- :004E793A 83C404 add esp, 00000004
- :004E793D 5D pop ebp
- :004E793E 5F pop edi
- :004E793F C3 ret
-
- Just find the conditional jump at 4E78E5 in the exe and change it to a non conditional jump
- Rerun the game and WHAM!! "SNDpathevent - PATHFINDER NOT INITIALIZED." error. Do the same as above,
- find the string ref and double click on it and here you are:
-
- * Referenced by a CALL at Addresses:
- |:00413684 , :004137BC , :00418D37 , :00418DAC , :00418E2E
- |:00418F1C , :00418FB3 <-- Called 7 times for this one
- |
- :004E797C 51 push ecx
- :004E797D 56 push esi
- :004E797E 55 push ebp
- :004E797F 803D94F6A10000 cmp byte ptr [00A1F694], 00
- :004E7986 744E je 004E79D6 <-- Take this jump to continue
- :004E7988 833DCCF6A10000 cmp dword ptr [00A1F6CC], 00000000
- :004E798F 744E je 004E79DF
- :004E7991 85C0 test eax, eax
- :004E7993 0F8C7C000000 jl 004E7A15
- :004E7999 8B0DECB95600 mov ecx, dword ptr [0056B9EC]
- :004E799F 8A4907 mov cl, byte ptr [ecx+07]
- :004E79A2 81E1FF000000 and ecx, 000000FF
- :004E79A8 39C8 cmp eax, ecx
- :004E79AA 7D69 jge 004E7A15
- :004E79AC 83FA01 cmp edx, 00000001
- :004E79AF 0F849B000000 je 004E7A50
- :004E79B5 66833DE6B9560001 cmp word ptr [0056B9E6], 0001
- :004E79BD 0F85B2000000 jne 004E7A75
- :004E79C3 66A3E8B95600 mov word ptr [0056B9E8], ax
- :004E79C9 668915EAB95600 mov word ptr [0056B9EA], dx
- :004E79D0 31C0 xor eax, eax
- :004E79D2 5D pop ebp
- :004E79D3 5E pop esi
- :004E79D4 59 pop ecx
- :004E79D5 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004E7986(C)
- |
- :004E79D6 B8F2FFFFFF mov eax, FFFFFFF2 <-- Getting here continues with the game
- :004E79DB 5D pop ebp
- :004E79DC 5E pop esi
- :004E79DD 59 pop ecx
- :004E79DE C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004E798F(C) <-- Getting here means NFS3 had an error
- |
- * Possible StringData Ref from Data Obj ->"cmn\spathold.c"
- |
- :004E79DF BD88BA5400 mov ebp, 0054BA88
-
- * Possible StringData Ref from Data Obj ->"SNDpathevent"
- |
- :004E79E4 B818BC5400 mov eax, 0054BC18
- :004E79E9 BAD0020000 mov edx, 000002D0
-
- * Possible StringData Ref from Data Obj ->"SNDpathevent - PATHFINDER NOT " <-- Print it!
- ->"INITIALIZED."
- |
- :004E79EE 6828BC5400 push 0054BC28
- :004E79F3 892D50315500 mov dword ptr [00553150], ebp
- :004E79F9 A354315500 mov dword ptr [00553154], eax
- :004E79FE 891558315500 mov dword ptr [00553158], edx
- :004E7A04 E80796F1FF call 00401010
- :004E7A09 B8F2FFFFFF mov eax, FFFFFFF2
- :004E7A0E 83C404 add esp, 00000004
- :004E7A11 5D pop ebp
- :004E7A12 5E pop esi
- :004E7A13 59 pop ecx
- :004E7A14 C3 ret
-
- Again, just find the conditional jump at 4E7986 in the exe and change it to a non conditional
- jump just like we did with the first error. Alright, rerun the game and WHAM!! "SNDpatheventinterrupt
- - PATHFINDER NOT INITIALIZED." error. Jeezzzz How many times is this going to happen? Here we go again,
- the same thing as above. Find the string ref and double click on it to get to this new routine:
-
- * Referenced by a CALL at Addresses:
- |:00413664 , :00418F93 <-- Only called twice
- |
- :004E7A88 53 push ebx
- :004E7A89 51 push ecx
- :004E7A8A 52 push edx
- :004E7A8B 55 push ebp
- :004E7A8C 89C2 mov edx, eax
- :004E7A8E 803D94F6A10000 cmp byte ptr [00A1F694], 00
- :004E7A95 0F84E0000000 je 004E7B7B <-- Take this jump to continue
- :004E7A9B 833DCCF6A10000 cmp dword ptr [00A1F6CC], 00000000
- :004E7AA2 0F84DD000000 je 004E7B85
- :004E7AA8 85D2 test edx, edx
- :004E7AAA 0F8C0C010000 jl 004E7BBC
- :004E7AB0 A1ECB95600 mov eax, dword ptr [0056B9EC]
- :004E7AB5 8A4007 mov al, byte ptr [eax+07]
- :004E7AB8 25FF000000 and eax, 000000FF
- :004E7ABD 39C2 cmp edx, eax
- :004E7ABF 0F8DF7000000 jnl 004E7BBC
- :004E7AC5 E86A970100 call 00501234
- :004E7ACA 0FBF0554B95600 movsx eax, word ptr [0056B954]
- :004E7AD1 C1E002 shl eax, 02
- :004E7AD4 89C1 mov ecx, eax
- :004E7AD6 C1E003 shl eax, 03
- :004E7AD9 29C8 sub eax, ecx
- :004E7ADB 8B0DF0B95600 mov ecx, dword ptr [0056B9F0]
- :004E7AE1 01C8 add eax, ecx
- :004E7AE3 31C9 xor ecx, ecx
- :004E7AE5 8A08 mov cl, byte ptr [eax]
- :004E7AE7 A1ECB95600 mov eax, dword ptr [0056B9EC]
- :004E7AEC 8A4007 mov al, byte ptr [eax+07]
- :004E7AEF 25FF000000 and eax, 000000FF
- :004E7AF4 0FAFC1 imul eax, ecx
- :004E7AF7 01D0 add eax, edx
- :004E7AF9 8B155CB95600 mov edx, dword ptr [0056B95C]
- :004E7AFF 31DB xor ebx, ebx
- :004E7B01 8A1C02 mov bl, byte ptr [edx+eax]
- :004E7B04 8D049D00000000 lea eax, dword ptr [4*ebx+00000000]
- :004E7B0B 8B1560B95600 mov edx, dword ptr [0056B960]
- :004E7B11 B904000000 mov ecx, 00000004
- :004E7B16 01D0 add eax, edx
- :004E7B18 8B00 mov eax, dword ptr [eax]
- :004E7B1A 0FC8 bswap eax
- :004E7B1C F7D9 neg ecx
- :004E7B1E 8D0CCD20000000 lea ecx, dword ptr [8*ecx+00000020]
- :004E7B25 D3E8 shr eax, cl
- :004E7B27 89C2 mov edx, eax
- :004E7B29 B864B95600 mov eax, 0056B964
- :004E7B2E E861070000 call 004E8294
- :004E7B33 85C0 test eax, eax
- :004E7B35 0F85BD000000 jne 004E7BF8
- :004E7B3B E860100000 call 004E8BA0
- :004E7B40 A358B95600 mov dword ptr [0056B958], eax
- :004E7B45 66891D54B95600 mov word ptr [0056B954], bx
- :004E7B4C BAFFFFFFFF mov edx, FFFFFFFF
- :004E7B51 668915E4B95600 mov word ptr [0056B9E4], dx
- :004E7B58 31DB xor ebx, ebx
- :004E7B5A 66891DE6B95600 mov word ptr [0056B9E6], bx
- :004E7B61 668915E8B95600 mov word ptr [0056B9E8], dx
- :004E7B68 66891DEAB95600 mov word ptr [0056B9EA], bx
- :004E7B6F E81C970100 call 00501290
- :004E7B74 31C0 xor eax, eax
- :004E7B76 5D pop ebp
- :004E7B77 5A pop edx
- :004E7B78 59 pop ecx
- :004E7B79 5B pop ebx
- :004E7B7A C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004E7A95(C)
- |
- :004E7B7B B8F2FFFFFF mov eax, FFFFFFF2 <-- Get here to continue
- :004E7B80 5D pop ebp
- :004E7B81 5A pop edx
- :004E7B82 59 pop ecx
- :004E7B83 5B pop ebx
- :004E7B84 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004E7AA2(C)
- |
- * Possible StringData Ref from Data Obj ->"cmn\spathold.c" <-- Getting here means NFS3 had an error (again!)
- |
- :004E7B85 BD88BA5400 mov ebp, 0054BA88
-
- * Possible StringData Ref from Data Obj ->"SNDpatheventinterrupt"
- |
- :004E7B8A B878BC5400 mov eax, 0054BC78
- :004E7B8F BA03030000 mov edx, 00000303
-
- * Possible StringData Ref from Data Obj ->"SNDpatheventinterrupt - PATHFINDER " <-- Print it
- ->"NOT INITIALIZED."
- |
- :004E7B94 6890BC5400 push 0054BC90
- :004E7B99 892D50315500 mov dword ptr [00553150], ebp
- :004E7B9F A354315500 mov dword ptr [00553154], eax
- :004E7BA4 891558315500 mov dword ptr [00553158], edx
- :004E7BAA E86194F1FF call 00401010
- :004E7BAF B8F2FFFFFF mov eax, FFFFFFF2
- :004E7BB4 83C404 add esp, 00000004
- :004E7BB7 5D pop ebp
- :004E7BB8 5A pop edx
- :004E7BB9 59 pop ecx
- :004E7BBA 5B pop ebx
- :004E7BBB C3 ret
-
- Alright, last time... if this doesn't work then we're going down the wrong trail with this. Find
- the conditional jump in the exe and change it to a NOP and a non conditional jump. Now finally run Need
- For Speed 3: Hot Pursuit!! Now you can play the game all the way through without any errors or crashes
- and more importantly, without the CD. What you have left is known as a CD rip. That is you've ripped
- out the need for anything that was left on the CD, usually music and movies. Anyways, once you have made
- all the patches you have finally crack NFS3. It took a lot of work, but it's worth it for this one!
-
- In step by step fasion:
-
- 1. Do a max install and then apply these edits:
- 2. Make the following edits by version:
-
- For the US CD version edit nfs3.exe
- =============================================
- CD check:
- Search for: E8 B4 25 01 00 at offset 668,007
- Change to : 90 90 90 90 90
-
- Kill intro video and demo videos
- Search for: 7D 08 31 C0 5D at offset 611,971
- Change to : 90 90 -- -- --
-
- Kill music at main menu and during races:
- Search for: 51 56 57 55 89 at offset 63,728
- Change to : C3 -- -- -- --
-
- Search for: E8 91 86 FD FF at offset 226,602
- Change to : 90 90 90 90 90
-
- Search for: E8 4A 80 F9 FF at offset 488,417
- Change to : 90 90 90 90 90
-
- Search for: E8 FA CF F6 FF at offset 666,561
- Chagne to : 90 90 90 90 90
-
- Ingnore sound errors due to no music
- Search for: 74 1C 83 3D 2C at offset 943,205
- Chagne to : EB -- -- -- --
-
- Search for: 74 4E 83 3D 2C at offset 943,366
- Change to : EB -- -- -- --
-
- Search for: 0F 84 E0 00 00 at offset 943,637
- Change to : 90 E9 -- -- --
-
-
- For "Network Play System" patch1 edit nfs3.exe
- =============================================
- CD check:
- Search for: E8 14 23 01 00 at offset 669,223
- Change to : B8 00 00 00 00
-
- Kill intro video and demo videos
- Search for: 7D 08 31 C0 5D at offset 613,187
- Change to : 90 90 -- -- --
-
- Kill music at main menu and during races:
- Search for: 51 56 57 55 89 at offset 63,984
- Change to : C3 -- -- -- --
-
- Search for: E8 91 84 FD FF at offset 227,370
- Change to : B8 00 00 00 00
-
- Search for: E8 BA 7D F9 FF at offset 489,329
- Change to : B8 00 00 00 00
-
- Search for: E8 3A CC F6 FF at offset 667,777
- Chagne to : B8 00 00 00 00
-
- Ingnore sound errors due to no music
- Search for: 74 1C 83 3D 2C at offset 945,381
- Chagne to : EB -- -- -- --
-
- Search for: 74 4E 83 3D 2C at offset 945,542
- Change to : EB -- -- -- --
-
- Search for: 0F 84 E0 00 00 at offset 945,813
- Change to : 90 E9 -- -- --
-
-
- For "Network Play System" patch2 edit nfs3.exe
- =============================================
- CD check:
- Search for: E8 14 23 01 00 at offset 669,207
- Change to : B8 00 00 00 00
-
- Kill intro video and demo videos
- Search for: 7D 08 31 C0 5D at offset 613,171
- Change to : 90 90 -- -- --
-
- Kill music at main menu and during races:
- Search for: 51 56 57 55 89 at offset 63,984
- Change to : C3 -- -- -- --
-
- Search for: E8 A1 84 FD FF at offset 227,354
- Change to : B8 00 00 00 00
-
- Search for: E8 CA 7D F9 FF at offset 489,313
- Change to : B8 00 00 00 00
-
- Search for: E8 4A CC F6 FF at offset 667,761
- Chagne to : B8 00 00 00 00
-
- Ingnore sound errors due to no music
- Search for: 74 1C 83 3D CC at offset 945,365
- Chagne to : EB -- -- -- --
-
- Search for: 74 4E 83 3D CC at offset 945,526
- Change to : EB -- -- -- --
-
- Search for: 0F 84 E0 00 00 at offset 945,797
- Change to : 90 E9 -- -- --
-
- Quite a bit of work for this one, but after a max install and these patches you can play the game
- without the CD being on line. Of course you loose the movies and music this way, but it's cracked.
-
- Static Vengeance
-
- NOTE: Thanks again to shadowRUNNER for the "better" kill music 51 -> C3 edit!
-